// Go作者版权所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package ld

import (
	"syscall"
	"unsafe"
)

func (out *OutBuf) fallocate(size uint64) error {
	stat, err := out.f.Stat()
	if err != nil {
		return err
	}
	// F_peoposmode从文件末尾进行分配，因此我们需要大小差异。
	// 显然，它使用分配的结尾，而不是分配的逻辑结尾
	// 档案。
	cursize := uint64(stat.Sys().(*syscall.Stat_t).Blocks * 512) // 分配大小
	if size <= cursize {
		return nil
	}

	store := &syscall.Fstore_t{
		Flags:   syscall.F_ALLOCATEALL,
		Posmode: syscall.F_PEOFPOSMODE,
		Offset:  0,
		Length:  int64(size - cursize),
	}

	_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(out.f.Fd()), syscall.F_PREALLOCATE, uintptr(unsafe.Pointer(store)))
	if errno != 0 {
		return errno
	}

	return nil
}

func (out *OutBuf) purgeSignatureCache() {
	// 显然，Darwin内核可能会在mmap中缓存代码签名。
	// 当我们映射输出缓冲区时，它没有代码签名
	// （因为我们还没有生成一个）。现在使内核缓存无效
	// 我们已经生成了签名。见第42684期。
	syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(&out.buf[0])), uintptr(len(out.buf)), syscall.MS_INVALIDATE)
	// 尽最大努力。忽略错误。
}
